/* ----------------------------------------------------------------------------------------------------------------
 *  AnimeRenderer
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.renderer 
{
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import pure.debug.Logger;
	import pure.engine.core.ProcessManager;
	import pure.engine.core.ITickListener;
	import pure.engine.renderer.sections.Action;
	import pure.engine.renderer.sections.Section;
	import pure.engine.renderer.sections.SectionManager;
	import pure.engine.core.ns_despair;
		
	use namespace ns_despair;
	
	/**
	 * 动画渲染器
	 * 
	 * [Author] - PURE
	 * 
	 * [Hint] - 当动画渲染器不可见时，任何操作无效化
	 *        - 在visible为true时，对动画渲染器进行操作
	 * 
	 * [Feature] - [-1]暂停，[0]停止，[1]播放，[2]重复
	 * 
	 */
public class AnimeRenderer extends Renderer implements IAnime, ITickListener
{

	
	
	
	//======================
	// Property
	//======================
	
	
	// 是否可见
	override public function set visible(b:Boolean):void
	{ 
		super.visible = b;
		if (b)
		{
			resume();
		}
		else
		{
			pause();
		}
	}
	
	
	/**
	 * 改变片段
	 */
	public function set section(v:String):void
	{
		if (m_sectionName != v)
		{
			setSection(v);
			m_pointer = 1;
			if (m_visible)
			{
				m_dirtyFlag = 2;
				this._setAnimeFlag(0);
			}
		}
	}
	
	/**
	 * 改变指针
	 */
	public function set pointer(v:int):void
	{
		if (m_visible && v != m_pointer)
		{
			m_pointer = v;
			
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
			this._setAnimeFlag(0);
		}
	}
	
	
	
	
	//======================
	// Base
	//======================
	
	
	/**
	 * 播放
	 * 
	 * [Param] - action    动作
	 * [Param] - section   片段
	 * [Param] - repeated  是否重复
	 * [Return] - 持续时间
	 */
	public function play(action:String, section:String = null, repeated:Boolean = false):void
	{
		_checkSection(section);
		_playAction(action, 0, 0, repeated)
	}
	
	
	/**
	 * 计时播放
	 * 
	 * [Param] - action    动作
	 * [Param] - duration  持续时间
	 * [Param] - section   片段
	 * [Param] - repeated  是否重复
	 */
	public function tick(action:String, duration:Number, section:String = null, repeated:Boolean = false):void
	{
		_checkSection(section);
		_playAction(action, 0, duration, repeated)
	}
	

	
	/**
	 * 获取持续时间
	 * 
	 * [Param] - actions  动作名字列表
	 */
	public function getDuration(...actions):Number
	{
		var duration:Number = 0;
		var actionName:String;
		var A:Action;
		var l:int = actions.length;
		
		while (--l > -1)
		{
			actionName = actions[l];
			
			if (!Boolean(A = m_section.getActionByName(actionName)))
			{
				Logger.reportError(this, 'getDuration', '片段<' + m_section.m_name +'>，不存在的动作<' + actionName +'>...');
			}
			
			duration += ((A.delay / m_animeSpeed + 0.5) >> 0) * A.group.length * 0.001;
		}
		return duration;
	}
	

	/**
	 * 暂停
	 */
	public function pause():void
	{
		if (m_animeFlag <= 0)  return;
		
		m_animeFlag     =  0;
	}
	
	
	/**
	 * 继续
	 */
	public function resume():void
	{
		//if (m_animeFlag > 0 && m_oldAnimeFlags == 0)  return;
		//
		//m_animeFlag  =  m_oldAnimeFlags;
	}
	
	
	/**
	 * 重置
	 * [Hint] - 回到当前动作起点
	 * 
	 * [Param] - autoPlay  是否自动播放
	 */
	public function reset(autoPlay:Boolean = true):void
	{
		if (m_animeFlag > 0)
		{
			cachedIndex = cachedTime = 0;
			if (!autoPlay)         m_animeFlag = 0;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	
	
	/**
	 * 暂停 / 继续
	 */
	public function togglePause():void
	{
		//if (m_animeFlag > 0)
		//{
			//stop();
		//}
		//else
		//{
			//resume()
		//}
	}
	

	/**
	 * 进程处理
	 */
	public function update(deltaTime:int):void 
	{
		var pointer:int;
		
		if (m_animeFlag > 0)
		{
			if ((cachedTime += deltaTime) >= cachedDelay)
			{
				// 完成
				if (++cachedIndex >= cachedLength) 
				{	
					// 循环
					if (m_animeFlag == 2)
					{
						cachedIndex = 0;
					}
					// 普通
					else
					{
						this._setAnimeFlag(0);
						return;
					}
				}
				// 指针
				if ((pointer = m_group[cachedIndex]) != m_pointer)
				{
					m_pointer = pointer;
					m_dirtyFlag = Boolean(m_dirtyFlag == 0) ? 1 : m_dirtyFlag;
				}
				cachedTime -=  cachedDelay;	
			}
		}
	}
	
	
	
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */



	/**
	 * 播放动作
	 * 
	 * [Feature] - ① 帧1-2-3-4...由最初帧到最后帧，改变次数为 numFrame
	 * 
	 * [Param] - actionName  动作名字
	 * [Param] - index       当前索引
	 * [Param] - duration    手动持续时间(毫秒)
	 * [Param] - flag        类型
	 * 
	 * [Return] - 持续时间，[-1]循环，[0]单帧，[1+]单程持续时间
	 */
	protected function _playAction(actionName:String, index:int, duration:int, repeated:Boolean):void 
	{
		var A:Action;
		
		if (!Boolean(A = m_section.getActionByName(actionName)))
		{
			Logger.reportError(this, '_playAction', '片段<' + m_section.m_name +'>，不存在的动作<' + actionName +'>...');
		}
		
		m_group       =  A.group;
		cachedLength  =  m_group.length;
		cachedIndex   =  index;
		m_pointer     =  m_group[index];
		m_dirtyFlag   =  Boolean(m_dirtyFlag == 0) ? 1 : m_dirtyFlag;
		
		if (cachedLength == 1) 
		{
			this._setAnimeFlag(0);
			return;
		}
		else
		{
			this._setAnimeFlag(repeated ? 2 : 1);
		}
		cachedTime = 0;
		
		// 默认
		if (duration <= 0)
		{
			cachedDelay = (A.delay / m_animeSpeed + 0.5) >> 0;
		}
		// 手动
		else
		{
			cachedDelay = (duration / cachedLength + 0.5) >> 0;
		}
	}
	
	
	/**
	 * 设置播放状态
	 * 
	 * [Param] - flag  动画状态
	 */
	protected function _setAnimeFlag(flag:int):void
	{
		if (flag <= 0 && m_animeFlag > 0)
		{
			ProcessManager.instance.removeTickListener(this);
		}
		else if (flag > 0 && m_animeFlag <= 0)
		{
			ProcessManager.instance.addTickListener(this, ProcessManager.ANIME);
			cachedTime = 0;
		}
		m_animeFlag = flag;
	}
	
	
	/**
	 * 设置片段
	 * 
	 * [Param] - section  片段名字
	 */
	ns_despair function setSection(section:String):void 
	{
		m_section  =  SectionManager.getSection(m_sectionName = section);
		m_x        =  m_section.m_x;
		m_y        =  m_section.m_y;
		m_range    =  m_section.m_range;
		
		if (m_visible && m_dirtyFlag > -1)  m_dirtyFlag = 2;
	}
	
	
	/**
	 * 检查片段是否变化
	 */
	ns_despair function _checkSection(section:String):void
	{
		if (section != null && m_sectionName != section)
		{
			m_section  =  SectionManager.getSection(m_sectionName = section);
			m_x        =  m_section.m_x;
			m_y        =  m_section.m_y;
			m_range    =  m_section.m_range;
			if (m_visible && m_dirtyFlag > -1)  m_dirtyFlag = 2;
		}
	}
	
	
	/**
	 * [Overwrite]
	 * 一级缓存
	 */
	override protected function _generatePrimaryImage():void 
	{
		m_imageA = m_section.getBitmapByPointer(m_pointer);
	}
	
	
	/**
	 * [Overwrite]
	 * 毁灭
	 */
	override ns_despair function destroy():void
	{
		m_section     =  null;
		m_group       =  null;
		this._setAnimeFlag(0);
		
		super.destroy();
	}
	

	
	
	
	
	
	
	//======================
	// Member
	//======================

	
	ns_despair static var m_animeSpeed:Number;  // 总动画速率
	
	ns_despair var m_section:Section;  // 片段加入后，渲染器destroy前，无法null.

	ns_despair var m_sectionName:String;  // 片段名字

	ns_despair var m_group:Vector.<int>;  // 当前组

	ns_despair var m_animeFlag:int, m_pointer:int = 1, uid:int = -1;

	
	//Memento 

	//======================
	// Cached Object
	//======================
	
	
	ns_despair var cachedIndex:int, cachedLength:int, cachedTime:int, cachedDelay:int;
	
}
}